package com.hu.juc.day01.T3;

import java.util.concurrent.TimeUnit;

/**
 * 题目:多线程8锁
 * 1.标准访问，请问先打印邮件还是短信？------邮件--》短信
 * 2.邮件暂停4秒钟，请问先打印邮件还是短信？------邮件--》短信
 * 3.新增一个hello(普通)方法，请问先打印邮件(4s)还是hello？------hello--》邮件--》短信
 * 4.两部手机，请问先打印邮件(4s)还是短信？------短信--》邮件
 * 5.两个静态同步方法，1部手机，请问先打印邮件(4s)还是短信？------邮件--》短信
 * 6.两个静态同步方法，2部手机，请问先打印邮件(4s)还是短信？------邮件--》短信
 * 7.一个普通同步方法，1个静态同步方法，1部手机，请问先打印邮件(4s)还是短信？------短信（静态同步方法）--》邮件（普通同步方法）
 * 8.一个普通同步方法，1个静态同步方法，2部手机，请问先打印邮件(4s)还是短信？------短信（静态同步方法）--》邮件（普通同步方法）
 *
 * 都换成静态同步方法后，情况又变化
 * new this,具体的一部部手机
 * 静态class，唯一的一个模板
 * 所有的非静态同步方法用的都是同一把锁——实例对象本身。
 * <
 * synchronized实现同步的基础: Java中的每一个对象都可以作为锁。
 * 具体表现为以下3种形式。
 * 对于普通同步方法，锁是当前实例对象。
 * 对于静态同步方法，锁是当前类的Class对象。
 * 对于同步方法块，锁是synchronized括号里配置的对象。
 *
 * 当一个线程试图访问同步代码块时，它首先必须得到锁。退出或抛出异常时必须释放锁。
 *
 * 也就是说如果一个实例对象的非静态（普通）同步方法获取锁后，该实例对象的其他非静态（普通）同步方法必须等待获取锁的方法释放锁后才能获取锁,
 * 可是别的实例对象的非静态（普通）同步方法因为跟该实例对象的非静态（普通）同步方法用的是不同的锁，
 * 所以无需等待该实例对象已获取锁的非静态（普通）同步方法释放锁就可以获取他们自己的锁。
 *
 * 所有的静态同步方法用的也是同一把锁——类对象本身，
 * 这两把锁（this/Class）是两个不同的对象，所以静态同步方法与非静态同步方法之间是不会有静态条件的。
 * 但是一-旦 一个静态同步方法获取锁后，其他的静态同步方法都必须等待该方法释放锁后才能获取锁，
 * 而不管是同一- 个实例对象的静态同步方法之间，
 * 还是不同的实例对象的静态同步方法之间，只要它们同一个类的实例对象!
 */
public class Lock8 {
    public static void main(String[] args) throws Exception {
        Phone phone = new Phone();
        Phone phone2 = new Phone();

        new Thread(() -> {
            phone.sendEmail();
        }, "A").start();

        try {
            TimeUnit.MILLISECONDS.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        new Thread(() -> {
            //phone.sendMSG();
            //phone2.sendMSG();
            phone.hello();
        }, "B").start();

        /*new Thread(() -> {
            phone.hello();
        }, "hello").start();*/
    }
}

